<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Advanced Relationships : DataMapper ORM - User Guide</title>

<link rel="shortcut icon" type="image/png" href="../images/favicon.png" />
<link rel="stylesheet" type="text/css" media="all" href="../css/userguide.css" />
<link rel="alternate" type="application/rss+xml" title="Datamapper ORM Updates Feed" href="/rss.xml" />

<meta http-equiv="expires" content="-1" />
<meta http-equiv= 'pragma' content="no-cache" />
<meta name="robots" content="all" />

</head>

<body>

<!-- START NAVIGATION -->
<div id="nav"><div id="nav_inner"></div></div>
<div id="nav2"><a name="top">&nbsp;</a><a id="nav_toggle" href="#"><img src="../images/nav_toggle_darker.jpg" width="154" height="43" border="0" title="Toggle Table of Contents" alt="Toggle Table of Contents" /></a></div>
<div id="masthead">
<table cellpadding="0" cellspacing="0" border="0" style="width:100%">
<tr>
<td><h1>DataMapper ORM</h1></td>
<td id="breadcrumb_right"><a href="toc.html">Table of Contents Page</a></td>
</tr>
</table>
</div>
<!-- END NAVIGATION -->

<!-- START BREADCRUMB -->
<table cellpadding="0" cellspacing="0" border="0" style="width:100%">
<tr>
<td id="breadcrumb">
<a href="/">Datamapper ORM Home</a> &nbsp;&#8250;&nbsp;
<a href="../index.html">User Guide Home</a> &nbsp;&#8250;&nbsp;
Advanced Relationships
</td>
</tr>

</table>
<!-- END BREADCRUMB -->

<br clear="all" />


<!-- START CONTENT -->
<div id="content">


<h1>Advanced Relationships</h1>

<p>Datamapper ORM has extended the ability of DataMapper to handle significantly more complex relationships, including:</p>
<ul>
	<li>Multiple Relationships to the Same Model</li>
	<li>Proper Self-Relationships</li>
	<li>Storing Additional Information on the Join Table</li>
	<li>Overriding the standard naming conventions</li>
	<li>Defining relationships after the model has been loaded</li>
</ul>

<h2>More Advanced Relationship Overview</h2>

<p>Before showing examples, let's review a normal relationship, and the information needed to make it work.  A normal relationship between two models is managed by the database structure, and a value stored on both models, in the <var><i>$has_many</i></var> and <var><i>$has_one</i></var> arrays.  This value tells DataMapper to look for the related model.  Internally, DataMapper knows that this model is related using the generated table and model names.</p>

<p>With advanced relationships, we can override the generated information, and even replace the <em>name</em> used to look for the relationship.  This allows us to relate the same object multiple times, as well as relate an object to itself.</p>

<h2>Extended Relationship Attributes</h2>

<p>Previously, a single value was stored per object in the <var><i>$has_many</i></var> and <var><i>$has_one</i></var> arrays.  To begin making more advanced relationships, we convert them into a <var><s>relationship key</s></var> and <kbd>attribute array()</kbd>:
<h3>Before</h3>
<pre>
<kbd>class </kbd><var>Post </var><kbd>extends </kbd><var><u>DataMapper</u> </var><kbd>{
    </kbd><var><i>$has_one</i> </var><kbd>= array(</kbd><dfn>'user'</dfn><kbd>);
}</kbd>
</pre>
<h3>After</h3>
<pre>
<kbd>class </kbd><var>Post </var><kbd>extends </kbd><var><u>DataMapper</u> </var><kbd>{
    </kbd><var><i>$has_one</i> </var><kbd>= array(
        </kbd><dfn><var><s>'user'</s></var> </dfn><kbd><em class="new">=&gt; array()</em>
    );
}</kbd>
</pre>

<p>Right now, nothing different will happen.  User will still be related to Post as <var>$post</var><kbd>-></kbd><var>user</var>.  To change the user into something else, we'll need to use some of the following four attributes.  You can specify any combination of them, but the most common are <var><s>class</s></var> and <dfn>other_field</dfn> together.</p>

<h3>Relationship name</h3>

<p>The key of the relationship array entry defines the relationship name. It is the one used in the code when you want to query the relation. In the example given above, the key used is <var><s>user</s></var>, so you would access this relation by using:</p>
<pre>
<samp>// define a new relationship for the Posts model
</samp><var>$p </var><kbd>= new </kbd><var>Post</var><kbd>(<dfn>1</dfn>);
</kbd><var>$p</var><kbd>-&gt;</kbd><var><s>user</s><kbd>-&gt;</kbd><var><u>get</u></var><kbd>();
</pre>

<h3>Attributes Table</h3>
<table cellpadding="0" cellspacing="1" border="0" class="tableborder">
<tr>
	<th>Name</th>
	<th>Description</th>
	<th>Default</th>
	<th>Common Usage</th>
</tr>
<tr>
	<td><var><s>class</s></var></td>
	<td>Tells DataMapper which class (model) this relationship points to.</td>
	<td><strong>key</strong></var> used on the array entry</td>
	<td>Almost always specified. Use it when the class name differs from the key used.</td>
</tr>
<tr>
	<td><dfn>other_field</dfn></td>
	<td>Tells DataMapper what the relationship looks like from <samp>class</samp>.</td>
	<td><var><b>$this</b></var><kbd>-&gt;</kbd><var><i>model</i></var></td>
	<td>Whenever the key relation of the other model is different than this models name.</td>
</tr>
<tr>
	<td>join_other_as</td>
	<td>Override the generated column name for the other model.</td>
	<td><strong>key</strong></var> on <var>$has_many</var> or <var>$has_one</var></td>
	<td>Used with custom column names, or in some unusual self-relationships.</td>
</tr>
<tr>
	<td>join_self_as</td>
	<td>Override the generated column name for this model.</td>
	<td><dfn>other_field</dfn></td>
	<td>Used with custom column names, or in some unusual self-relationships.</td>
</tr>
<tr>
	<td>join_table</td>
	<td>Override the generated table name for this relation.</td>
	<td><var>''</var></td>
	<td>Custom table name. Also used in some multi-table (more than two) relationships.</td>
</tr>
<tr>
	<td>model_path</td>
	<td>Alternative location for this model.</td>
	<td><b>APPPATH</b></td>
	<td>Used in a modular context, where models are used cross-module. Note that is it the module path, <b>NOT</b> the model path!</td>
</tr>
<tr>
	<td>auto_populate</td>
	<td>Autopopulate the objects for this relation.</td>
	<td><var><b>FALSE</b></var></td>
	<td>Use the same as the global settings <var>$auto_populate_has_one</var> and <var>$auto_populate_has_many</var>, but then on a per-relationship basis.</td>
</tr>
<tr>
	<td>cascade_delete</td>
	<td>Delete the relation when deleting the parent object.</td>
	<td><var><b>TRUE</b></var></td>
	<td>Use the same as the configuration variable and the global setting <var>$cascade_delete</var>, but then on a per-relationship basis.</td>
</tr>
</table>

<h2>Manually defining the relationship</h2>

<p>Under normal circumstances, this is not something you should do, but it will help you understand how Datamapper generates the relationship definition between two models, and what the role of the different fields in the relationship definition is.</p>
<p>Consider the models Author and Book. An author can write multiple books, a book can have multiple writers, which makes this a many-to-many relationship. You can define this by a simple has_many entry in both models, and Datamapper will generate the rest. The following definition shows you the advanced relationship definition that Datamapper will generate internally for this relation.</p>

<h3>Author</h3>
<pre>
<kbd>class </kbd><var>Author </var><kbd>extends </kbd><var><u>DataMapper</u> </var><kbd>{
    </kbd><var><i>$has_many</i> </var><kbd>= array(
        </kbd><strong>'book'</strong> <kbd>=&gt; array(			<samp>// in the code, we will refer to this relation by using the object name 'book'</samp>
            </kbd>'class' <kbd>=&gt; </kbd><dfn>'book'</dfn><kbd>,			<samp>// This relationship is with the model class 'book'</samp>
            </kbd>'other_field' <kbd>=&gt; </kbd><dfn>'author'</dfn><kbd>,		<samp>// in the Book model, this defines the array key used to identify this relationship</samp>
            </kbd>'join_self_as' <kbd>=&gt; </kbd><dfn>'author'</dfn><kbd>,		<samp>// foreign key in the (relationship)table identifying this models table. The column name would be 'author_id'</samp>
            </kbd>'join_other_as' <kbd>=&gt; </kbd><dfn>'book'</dfn><kbd>,		<samp>// foreign key in the (relationship)table identifying the other models table as defined by 'class'. The column name would be 'book_id'</samp>
            </kbd>'join_table' <kbd>=&gt; </kbd><dfn>'authors_books'</dfn><kbd>)	<samp>// name of the join table that will link both Author and Book together</samp>
    );
}</kbd>
</pre>

<h3>Book</h3>
<pre>
<kbd>class </kbd><var>Book </var><kbd>extends </kbd><var><u>DataMapper</u> </var><kbd>{
    </kbd><var><i>$has_many</i> </var><kbd>= array(
        </kbd><strong>'author'</strong> <kbd>=&gt; array(			<samp>// in the code, we will refer to this relation by using the object name 'author'</samp>
            </kbd>'class' <kbd>=&gt; </kbd><dfn>'author'</dfn><kbd>,		<samp>// This relationship is with the model class 'author'</samp>
            </kbd>'other_field' <kbd>=&gt; </kbd><dfn>'book'</dfn><kbd>,		<samp>// in the Author model, this defines the array key used to identify this relationship</samp>
            </kbd>'join_self_as' <kbd>=&gt; </kbd><dfn>'book'</dfn><kbd>,		<samp>// foreign key in the (relationship)table identifying this models table. The column name would be 'book_id'</samp>
            </kbd>'join_other_as' <kbd>=&gt; </kbd><dfn>'author'</dfn><kbd>,	<samp>// foreign key in the (relationship)table identifying the other models table as defined by 'class'. The column name would be 'author_id'</samp>
            </kbd>'join_table' <kbd>=&gt; </kbd><dfn>'authors_books'</dfn><kbd>)	<samp>// name of the join table that will link both Author and Book together</samp>
    );
}</kbd>
</pre>

<h3>Some common naming rule deviations</h3>

<p>
	You want to add a prefix or suffix to your class names to avoid class name collisions (with for example controllers or CodeIgniter libraries).
	<ul><li>If you would use the '_model' prefix on your classes, use the <dfn>class</dfn> names 'book_model' and 'author_model' instead.</li></ul>
	<ul><li>You would still use <var>$obj->book</var> and <var>$obj->author</var> to access the relationship.</li></ul>
</p>
<p>
	You want to use alternative names to specify the relationship in the code. Say want to use <var>$obj->writer</var> instead of <var>$obj->author</var>.
	<ul><li>In the Author class, use 'writer' for the <dfn>other_field</dfn> value.</li></ul>
	<ul><li>In the Book class, use 'writer' for the array key value.</li></ul>
</p>
<p>
	You want to use alternative table name for the relation. For example, you prefer 'written_books'.
	<ul><li>In both the Author and the Book classes, use 'written_books' for the <dfn>join_table</dfn> value.</li></ul>
</p>
<p>
You want to use alternative name for a foreign key column name. Say want to use <kbd>writer_id</kbd> instead of <kbd>author_id</kbd>.
	<ul><li>In the Author class, use 'writer' for the <dfn>join_self_as</dfn> value.</li></ul>
	<ul><li>In the Book class, use 'writer' for the <dfn>join_other_as</dfn> value.</li></ul>
</p>

<h2>Multiple Relationships to the Same Model</h2>

<p>This is the most common usage, and is used in almost every project.  There is a simple pattern to defining this relationship.</p>

<p>Post has a creator and an editor, which may be different users.  Here's how to set that up.</p>
<h3>Post</h3>
<pre>
<kbd>class </kbd><var>Post </var><kbd>extends </kbd><var><u>DataMapper</u> </var><kbd>{
    </kbd><var><i>$has_one</i> </var><kbd>= array(
        </kbd><strong>'creator'</strong> <kbd>=&gt; array(
            </kbd>'class' <kbd>=&gt; </kbd><dfn><var><s>'user'</s></var></dfn><kbd>,
            </kbd>'other_field' <kbd>=&gt; </kbd><dfn>'created_post'
        </dfn><kbd>),
        </kbd><strong>'editor'</strong> <kbd>=&gt; array(
            </kbd>'class' <kbd>=&gt; </kbd><dfn><var><s>'user'</s></var></dfn><kbd>,
            </kbd>'other_field' <kbd>=&gt; </kbd><dfn>'edited_post'
        </dfn><kbd>)
    );
}</kbd>
</pre>
<h3>User</h3>
<pre>
<kbd>class </kbd><var>User </var><kbd>extends </kbd><var><u>DataMapper</u> </var><kbd>{
    </kbd><var><i>$has_many</i> </var><kbd>= array(
        </kbd><strong>'created_post'</strong> <kbd>=&gt; array(
            </kbd>'class' <kbd>=&gt; </kbd><dfn><var><s>'post'</s></var></dfn><kbd>,
            </kbd>'other_field' <kbd>=&gt; </kbd><dfn>'creator'
        </dfn><kbd>),
        </kbd><strong>'edited_post'</strong> <kbd>=&gt; array(
            </kbd>'class' <kbd>=&gt; </kbd><dfn><var><s>'post'</s></var></dfn><kbd>,
            </kbd>'other_field' <kbd>=&gt; </kbd><dfn>'editor'
        </dfn><kbd>)
    );
}</kbd>
</pre>

<p>A couple of things to note here.</p>
<ul>
	<li>The relationship is now defined by the <strong>relationship key</strong> on either side, <em>not</em> the model name.  This has now become the <em>only way</em> to look up the relationship.</li>
	<li>The <strong>key</strong> on one side of the relationship becomes the <dfn>other_field</dfn> on the opposite side, and vice-versa.</li>
	<li>Because we need a way to specify the difference between posts that were edited and those that were created, we have to declare the slightly unusual <strong>edited_post</strong> and <strong>created_post</strong> relationships.  These could have any name, as long as they were unique and mirrored on Post.</li>
	<li>The table structure is going to be a little different now.</li>
</ul>

<h2 id="reciprocal">Many-to-Many Reciprocal Self Relationships</h2>

<p>In this type of relationship, you have records that related to each other, and where saving or deleting the relationship in one direction should also maintain the relationship in the reverse direction.</p>

<p>The best example I can think of is in the area of genealogy.</p>
<p>Suppose you have a table with information about people, and you want to relate them
(grandparent-parent-child etc). You always have to make the relation both ways, since it can’t be that person A is the child of person B,
but B is not the parent of A. If you define this relation as reciprocal, when you save the relation between A and B, automatically the
relation between B and A is saved as well. And when you delete the relationship, both relations are deleted.</p>

<pre>
<kbd>class </kbd><var>Person </var><kbd>extends </kbd><var><u>DataMapper</u> </var><kbd>{
    </kbd><var><i>$has_many</i> </var><kbd>= array(
        </kbd><strong>'related_person'</strong> <kbd>=&gt; array(
            </kbd>'class' <kbd>=&gt; </kbd><dfn><var><s>'person'</s></var></dfn><kbd>,
            </kbd>'other_field' <kbd>=&gt; </kbd><dfn>'person'</var></dfn><kbd>,
            </kbd>'reciprocal' <kbd>=&gt; </kbd><dfn>TRUE</dfn><kbd>
        ),
        </kbd><strong>'person'</strong> <kbd>=&gt; array(
            </kbd>'other_field' <kbd>=&gt; </kbd><dfn>'related_person'</var></dfn><kbd>,
            </kbd>'reciprocal' <kbd>=&gt; </kbd><dfn>TRUE</dfn><kbd>
        )
    );
}
</pre>
<p>To get this to work, you will need:</p>
<ul>
	<li>You need a relationship table to define this many-to-many relation, which is this case would be called '<dfn>persons_persons</dfn>'.</li>
	<li>This table needs to contain a column called '<dfn>person_id</dfn>' and a column called '<dfn>related_person_id</dfn>'.</li>
</ul>
<p class="note">Note that this defined per relation. If you want this to work both ways, you need to specify the '<dfn>reciprocal</dfn>' setting on <b>BOTH</b> relationship definitions.</p>
<h2>Setting up the Table Structure with Advanced Relationships</h2>
<p>The table structure has one key difference.  While the names of the tables is still determined using the plural form of the model, the <em>column names</em> are now defined using the <strong>relationship key</strong>.</p>

<h3>In-table Foreign Keys</h3>
<p>If we decide to use in-table foreign keys, the <b>posts</b> table looks like this:</p>
<table cellpadding="0" cellspacing="1" border="0" class="tableborder">
<tr>
	<th>id</th>
	<th>title</th>
	<th>body</th>
	<th>creator_id</th>
	<th>editor_id</th>
</tr>
<tr>
	<td>1</td>
	<td>Hello World</td>
	<td>My first post</td>
	<td>4</td>
	<td>4</td>
</tr>
<tr>
	<td>2</td>
	<td>Another Post</td>
	<td>My second post (Edited by Joe)</td>
	<td>4</td>
	<td>6</td>
</tr>
</table>

<h3>Dedicated Join Table</h3>
<p>If we decide to use a join table, that table is a little different.  The table is still called <b>posts_users</b>, but the table now looks like this:</p>
<table cellpadding="0" cellspacing="1" border="0" class="tableborder">
<tr>
	<th>id</th>
	<th>creator_id</th>
	<th>created_post_id</th>
	<th>editor_id</th>
	<th>edited_post_id</th>
</tr>
<tr>
	<td>1</td>
	<td>4</td>
	<td>1</td>
	<td>NULL</td>
	<td>NULL</td>
</tr>
<tr>
	<td>2</td>
	<td>NULL</td>
	<td>NULL</td>
	<td>4</td>
	<td>1</td>
</tr>
<tr>
	<td>3</td>
	<td>4</td>
	<td>2</td>
	<td>NULL</td>
	<td>NULL</td>
</tr>
<tr>
	<td>4</td>
	<td>NULL</td>
	<td>NULL</td>
	<td>6</td>
	<td>2</td>
</tr>
</table>
<p>This stores the same information.  We only have the option in this case because the <b>posts</b> side was <var><i>$has_one</i></var>.  If posts could have many creators or many editors, then that would have to be stored in this table.</p>

<h2>Multi-table Relationships</h2>
<p>In normal circumstances, you will always have a relationship between two tables, either in a one-to-one, one-to-many, or many-to-many relationship.</p>
<p>Occasionally however, you might have a need to define a relationship between more than two tables. In this case, you will have to create a joined table with more than two foreign keys, one to each of the tables involved in the relationship.
In this situation Datamapper can no longer automatically generate the name of the joined table. Instead, you will have to use the <kbd>join_table</kbd> to manually define the name of the joined table.</p>
<p>When you use this option, make sure you define the same table name in all models!</p>

<h2>Self Relationships</h2>
<p>Technically, self-relationships are the same as having multiple relationships to the same object.  There is one key difference: the table names.  First, we'll set the class up, then I'll show you the table name.</p>

<h3>Post has Many Related Posts</h3>
<p>We want to have the ability to track related posts.  Here's the model:</p>

<pre>
<kbd>class </kbd><var>Post </var><kbd>extends </kbd><var><u>DataMapper</u> </var><kbd>{
    </kbd><var><i>$has_one</i> </var><kbd>= array(
        </kbd><dfn>'creator' </dfn><kbd>=&gt; array(
            </kbd><dfn>'class' </dfn><kbd>=&gt; </kbd><dfn>'user'</dfn><kbd>,
            </kbd><dfn>'other_field' </dfn><kbd>=&gt; </kbd><dfn>'created_post'
        </dfn><kbd>),
        </kbd><dfn>'editor' </dfn><kbd>=&gt; array(
            </kbd><dfn>'class' </dfn><kbd>=&gt; </kbd><dfn>'user'</dfn><kbd>,
            </kbd><dfn>'other_field' </dfn><kbd>=&gt; </kbd><dfn>'edited_post'
        </dfn><kbd>)
    );</kbd>
<em class="new">    <var><i>$has_many</i> </var><kbd>= array(
        </kbd><dfn>'relatedpost' </dfn><kbd>=&gt; array(
            </kbd><dfn>'class' </dfn><kbd>=&gt; </kbd><dfn>'post'</dfn><kbd>,
            </kbd><dfn>'other_field' </dfn><kbd>=&gt; </kbd><dfn>'post'
        </dfn><kbd>),
        </kbd><dfn>'post' </dfn><kbd>=&gt; array(
            </kbd><dfn>'other_field' </dfn><kbd>=&gt; </kbd><dfn>'relatedpost'
        </dfn><kbd>)
    );</em>
}</kbd>
</pre>

<p>Some notes about this form:</p>
<ul>
	<li>This shows how you can still have one side of the relationship retain the model name.  In this case, <var>$post</var><kbd>-&gt;</kbd><var><em>post</em></var> will show the up-stream relationships, while <var>$post</var><kbd>-&gt;</kbd><var><em>relatedpost</em></var> shows the downstream.</li>
	<li>This is a Many to Many relationship, so we'll need a dedicated table.</li>
	<li>This is currently a one-way relationship, so each related post will have to be saved inversely as well.</li>
</ul>

<h2>Naming Self-Relationship Tables</h3>
<p>Self relationships are special because the join table name is <em>not</em> generated from the table name of the object, but instead from the <key>relationship key</key>s used to define the relationship.</p>
<p>For the example above, the table looks like this:</p>
<h3>posts_relatedposts</h3>
<table cellpadding="0" cellspacing="1" border="0" class="tableborder">
<tr>
	<th>id</th>
	<th>post_id</th>
	<th>relatedpost_id</th>
</tr>
<tr>
	<td>1</td>
	<td>1</td>
	<td>2</td>
</tr>
<tr>
	<td>2</td>
	<td>2</td>
	<td>1</td>
</tr>
</table>

<p>This allows us to relate Post #1 -&gt; Post #2, as well as relating Post #2 -&gt; Post #1.</p>

<h2 id="runtime">Defining relations after the model has been loaded</h2>
<p>Sofar, all relationship definitions have been static, defined as a property of the datamapper model.</p>
<p>For most applications, this works fine. However, there are situation where you would like to define the relationships between models at runtime.
This is particularly true in a modular environment, where a module can introduce new models that have a relationship with models from an other module,
or from the application itself.</p>
<p>Obviously you can't define these relationships in the model itself, as the name of the model might not be known at the time of writing, or the models database structure might not be available until the module has been installed.</p>
<h3>Runtime relationship definition</h3>
<p>Until now, to define a relationship you are used to code it like this:</p>
<pre>
<kbd>class </kbd><var>Post </var><kbd>extends </kbd><var><u>DataMapper</u> </var><kbd>{
    </kbd><var><i>$has_one</i> </var><kbd>= array(</kbd><dfn>'user'</dfn><kbd>);
}</kbd>
</pre>
<p>This relation can also be defined at runtime:</p>
<pre>
<samp>// define a new relationship for the Posts model
</samp><var>$p </var><kbd>= new </kbd><var>Post</var><kbd>();
</kbd><var>$p</var><kbd>-&gt;</kbd><var><u>has_one</u></var><kbd>(</kbd><dfn>'user'</dfn><kbd>);
</pre>
<p>You can also do this for advanced relationships. The example used previously</p>
<pre>
<kbd>class </kbd><var>Post </var><kbd>extends </kbd><var><u>DataMapper</u> </var><kbd>{
    </kbd><var><i>$has_one</i> </var><kbd>= array(
        </kbd><strong>'creator'</strong> <kbd>=&gt; array(
            </kbd>'class' <kbd>=&gt; </kbd><dfn><var><s>'user'</s></var></dfn><kbd>,
            </kbd>'other_field' <kbd>=&gt; </kbd><dfn>'created_post'
        </dfn><kbd>),
        </kbd><strong>'editor'</strong> <kbd>=&gt; array(
            </kbd>'class' <kbd>=&gt; </kbd><dfn><var><s>'user'</s></var></dfn><kbd>,
            </kbd>'other_field' <kbd>=&gt; </kbd><dfn>'edited_post'
        </dfn><kbd>)
    );
}</kbd>
</pre>
<p>can be defined at runtime like this:</p>
<pre>
<samp>// define new relationships for the Posts model</samp>
<var>$p </var><kbd>= new </kbd><var>Post</var><kbd>();
<var>$relation </var><kbd>= array(
	</kbd>'class' <kbd>=&gt; </kbd><dfn><var><s>'user'</s></var></dfn><kbd>,
	</kbd>'other_field' <kbd>=&gt; </kbd><dfn>'created_post'
</dfn><kbd>);
</kbd><var>$p</var><kbd>-&gt;</kbd><var><u>has_one</u></var><kbd>(</kbd><dfn>'creator'</dfn><kbd>, </kbd><var><i>$relation</i></var><kbd>);

<var>$relation </var><kbd>= array(
	</kbd>'class' <kbd>=&gt; </kbd><dfn><var><s>'user'</s></var></dfn><kbd>,
	</kbd>'other_field' <kbd>=&gt; </kbd><dfn>'edited_post'
</dfn><kbd>);
</kbd><var>$p</var><kbd>-&gt;</kbd><var><u>has_one</u></var><kbd>(</kbd><dfn>'editor'</dfn><kbd>, </kbd><var><i>$relation</i></var><kbd>);
</pre>

<br />

<p>And there you have it.  Advanced relationships to allow you to manage more complex data structures.  On to <a href="controllers.html">DataMapper in Controllers</a> so we can actually <em>use</em> this information!</p>

</div>
<!-- END CONTENT -->


<div id="footer">
<p>
<span id="footer_previous">Previous Topic:&nbsp;&nbsp;<a href=""></a>
&nbsp;&nbsp;&nbsp;&middot;&nbsp;&nbsp;</span>
<a href="#top">Top of Page</a>&nbsp;&nbsp;&nbsp;&middot;&nbsp;&nbsp;
<a href="../index.html">User Guide Home</a>
<span id="footer_next">&nbsp;&nbsp;&nbsp;&middot;&nbsp;&nbsp;
Next Topic:&nbsp;&nbsp;<a href=""></a></span>
</p>
<div id="copyrights">
<p><a href="/">Datamapper ORM</a> &nbsp;&middot;&nbsp; Copyright &copy; 2010-2011 &nbsp;&middot;&nbsp; Harro "WanWizard" Verton</p>
<p><a href="license.html">Other License Information</a></p>
</div>
</div>

<script type="text/javascript" src="../js/mootools.js"></script>
<script type="text/javascript" src="../js/menu.js"></script>
<script type="text/javascript">
<!--
	window.addEvent('domready', function() {

		// Create Menu
		var menu = new Menu({
			basepath: '../',
			pagespath: ''
		});

	});
//-->
</script>
</body>
</html>
